package com.xmb.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xmb.common.constants.ExchangeTypeEnum;
import com.xmb.common.constants.RewardTypeEnum;
import com.xmb.common.dao.XmbOrderRewardSettingMapper;
import com.xmb.common.dao.XmbSpreadRewardSettingMapper;
import com.xmb.common.dao.XmbUserRelationMapper;
import com.xmb.common.entity.*;
import com.xmb.common.entity.reward.ActivityRewardInfo;
import com.xmb.common.entity.reward.RewardSpecificRule;
import com.xmb.common.entity.structure.FxUserGroupDiscountConfig;
import com.xmb.common.exception.BusinessException;
import com.xmb.common.interceptor.CurrentContextUser;
import com.xmb.common.log.LoggerInterface;
import com.xmb.common.remote.entity.XcxUser;
import com.xmb.common.remote.service.UserService;
import com.xmb.common.service.*;
import com.xmb.common.utils.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lyndon on 2019/4/10.
 */
@Service
public class SpreadRewardServiceImpl implements SpreadRewardService,LoggerInterface{

    @Resource
    private UserService userService;

    @Resource
    private SprendRewardRecordService sprendRewardRecordService;

    @Resource
    private UserBonusService bonusService;

    @Resource
    private UserBalanceService balanceService;

    @Resource
    private UserScoreService scoreService;

    @Resource
    private XmbUserRelationMapper userRelationMapper;

    @Resource
    private UserGroupService userGroupService;


    @Resource
    private XmbConstantMessageService constantMessageService;

    @Resource
    private XmbSpreadRewardSettingMapper spreadRewardSettingMapper;

    @Resource
    private XmbOrderRewardSettingMapper orderRewardSettingMapper;

    @Override
    public Long giftReward(XmbSpreadRewardSetting spreadRewardSetting,String shareUserNo) {
        XcxUser xcxUser = new XcxUser();
        xcxUser.setId(CurrentContextUser.get().getUserId());
        xcxUser = userService.selectOneUser(xcxUser);
        if (xcxUser == null) {
            throw new BusinessException("查询不到当前用户");
        }
        XcxUser shareUser = new XcxUser();
        shareUser.setUserNo(shareUserNo);
        shareUser = userService.selectOneUser(shareUser);
        if (shareUser == null) {
            throw new BusinessException("查询不到分享者的用户信息");
        }
        FxUserGroupDiscountConfig discountConfig = this.getFxUserGroupDiscount(shareUser);
        return this.insertDb(xcxUser,shareUser,spreadRewardSetting,discountConfig);
    }

    @Override
    public void createRelationShip(String shareUserNo) {
        XcxUser xcxUser = new XcxUser();
        xcxUser.setId(CurrentContextUser.get().getUserId());
        xcxUser = userService.selectOneUser(xcxUser);
        if (xcxUser == null) {
            throw new BusinessException("查询不到当前用户");
        }

        XcxUser shareUser = new XcxUser();
        shareUser.setUserNo(shareUserNo);
        shareUser = userService.selectOneUser(shareUser);
        if (shareUser == null) {
            throw new BusinessException("查询不到分享者的用户信息");
        }
        // 如果我没有A级，则分享者就是我的A级,依次类推
        // 非种子用户,没有上级,不能是分享者的上级 才能建立关系
        if (xcxUser.getIsSeedUser()) {
            logger.info("种子用户，不需要绑定上下级");
            return;
        }
        if (xcxUser.getaHigherId() != null
                && xcxUser.getaHigherId() >= 0L) {
            logger.info("当前用户已经有上级，不需要绑定上下级");
            return;
        }
        if (xcxUser.getId().equals(shareUser.getId())
                || xcxUser.getId().equals(shareUser.getaHigherId())
                || xcxUser.getId().equals(shareUser.getbHigherId())
                || xcxUser.getId().equals(shareUser.getcHigherId())) {
            logger.info("当前用户是分享者的上级，不需要绑定上下级");
            return;
        }

        logger.info("分享者的用户信息为：{}", JSON.toJSON(shareUser));

        // 更新用户信息
        xcxUser.setaHigherId(shareUser.getId());
        xcxUser.setaHigherName(shareUser.getNickName());
        xcxUser.setbHigherId(shareUser.getaHigherId());
        xcxUser.setbHigherName(shareUser.getaHigherName());
        xcxUser.setcHigherId(shareUser.getbHigherId());
        xcxUser.setcHigherName(shareUser.getbHigherName());
        if (shareUser.getIsAgent()) {
            xcxUser.setwHigherId(shareUser.getId());
            xcxUser.setwHigherName(shareUser.getNickName());
        } else {
            xcxUser.setwHigherId(shareUser.getwHigherId());
            xcxUser.setwHigherName(shareUser.getwHigherName());
        }
        userService.updateUser(xcxUser);

        // 建立关系
        XmbUserRelation userRelation = new XmbUserRelation();
        userRelation.setUserId(xcxUser.getId());
        userRelation.setaHigherId(shareUser.getId());
        userRelation.setbHigherId(shareUser.getaHigherId());
        userRelation.setcHigherId(shareUser.getbHigherId());
        userRelation.setAgentId(shareUser.getwHigherId());
        userRelationMapper.insertSelective(userRelation);
    }

    @Override
    public List<RewardSpecificRule> getRewardRule(Long activityId) {
        List<RewardSpecificRule> specificRuleList = new ArrayList<>();
        XmbConstantMessage shareMessage
                = constantMessageService.findXmbConstantMessage("marketing_reward","share");
        if (shareMessage == null) {
            throw new BusinessException("没有找到营销奖励规则模板配置，请检查配置");
        }

        XmbSpreadRewardSetting spreadRewardSetting = spreadRewardSettingMapper.findByActivityId(activityId);
        if (spreadRewardSetting != null) {
            String str = String.format(shareMessage.getBusinessValue(),
                    RewardTypeEnum.getEnumByType(spreadRewardSetting.getPromotionRewardType()).getDesc(),
                    spreadRewardSetting.getPromotionSelfReward(),
                    spreadRewardSetting.getPromotionAReward(),
                    spreadRewardSetting.getPromotionBReward(),
                    spreadRewardSetting.getPromotionCReward(),
                    spreadRewardSetting.getPromotionWReward());
            RewardSpecificRule shareRule = JSONObject.parseObject(str,RewardSpecificRule.class);
            specificRuleList.add(shareRule);
        }


        XmbConstantMessage orderMessage
                = constantMessageService.findXmbConstantMessage("marketing_reward","order");
        if (orderMessage == null) {
            throw new BusinessException("没有找到分销奖励规则模板配置，请检查配置");
        }

        XmbOrderRewardSetting orderRewardSetting = orderRewardSettingMapper.findXmbOrderRewardSettingBySenceId(activityId);
        if (orderRewardSetting != null) {
            String str = String.format(orderMessage.getBusinessValue(),
                    RewardTypeEnum.getEnumByType(orderRewardSetting.getPromotionRewardType()).getDesc(),
//                    orderRewardSetting.getPromotionSelfReward(),
                    orderRewardSetting.getPromotionAReward(),
                    orderRewardSetting.getPromotionBReward(),
                    orderRewardSetting.getPromotionCReward(),
                    orderRewardSetting.getPromotionWReward());
            RewardSpecificRule orderRule = JSONObject.parseObject(str,RewardSpecificRule.class);
            specificRuleList.add(orderRule);
        }

        if (specificRuleList.isEmpty()) {
            throw new BusinessException("没有找到活动的奖励配置信息");
        }
        return specificRuleList;
    }

    @Override
    public ActivityRewardInfo getShareRewardList(Long activityId) {
        Long userId = CurrentContextUser.get().getUserId();
        String exchangeType = ExchangeTypeEnum.share_reward.name();
        // 营销奖励
        XmbSpreadRewardSetting spreadRewardSetting = spreadRewardSettingMapper.findByActivityId(activityId);
        if (spreadRewardSetting != null) {
            return this.getRewardInfo(userId,activityId,exchangeType,spreadRewardSetting.getPromotionRewardType());
        }
        return null;
    }

    @Override
    public ActivityRewardInfo getOrderRewardList(Long activityId) {
        Long userId = CurrentContextUser.get().getUserId();
        String exchangeType = ExchangeTypeEnum.order_reward.name();
        // 分销奖励
        XmbOrderRewardSetting orderRewardSetting = orderRewardSettingMapper.findXmbOrderRewardSettingBySenceId(activityId);
        if (orderRewardSetting != null) {
            return this.getRewardInfo(userId,activityId,exchangeType,orderRewardSetting.getPromotionRewardType());
        }
        return null;
    }

    private ActivityRewardInfo getRewardInfo (Long userId,Long activityId,String exchangeType, String rewardType) {
        ActivityRewardInfo rewardInfo  = new ActivityRewardInfo();
        // 获取分销奖励
        // 奖金
        if (RewardTypeEnum.bonus.name().equals(rewardType)) {
            List<XmbUserBonusBlotter> bonusBlotterList = bonusService.getBonusList(userId,activityId,exchangeType);
            rewardInfo.setRewardBlotterList(bonusBlotterList);
            rewardInfo.setTotalSize(bonusBlotterList.size());
            rewardInfo.setRewardDesc(RewardTypeEnum.bonus.getDesc());
            rewardInfo.setTotalAmount(bonusBlotterList.stream().map(XmbUserBonusBlotter::getExchangeAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        }

        // 积分
        if (RewardTypeEnum.score.name().equals(rewardType)) {
            List<XmbUserScoreBlotter> scoreBlotterList = scoreService.getScoreList(userId,activityId,exchangeType);
            rewardInfo.setRewardBlotterList(scoreBlotterList);
            rewardInfo.setTotalSize(scoreBlotterList.size());
            rewardInfo.setRewardDesc(RewardTypeEnum.score.getDesc());
            rewardInfo.setTotalAmount(scoreBlotterList.stream().map(XmbUserScoreBlotter::getExchangeAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        }

        // 余额
        if (RewardTypeEnum.balance.name().equals(rewardType)) {
            List<XmbUserBalanceBlotter> userBalanceBlotters =  balanceService.getBalanceList(userId,activityId,exchangeType);
            rewardInfo.setRewardBlotterList(userBalanceBlotters);
            rewardInfo.setTotalSize(userBalanceBlotters.size());
            rewardInfo.setRewardDesc(RewardTypeEnum.balance.getDesc());
            rewardInfo.setTotalAmount(userBalanceBlotters.stream().map(XmbUserBalanceBlotter::getExchangeAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        }
        return rewardInfo;
    }

    /**
     * 获取各个等级的营销比例
     * @param shareUser
     * @return
     */
    private FxUserGroupDiscountConfig getFxUserGroupDiscount(XcxUser shareUser) {
        FxUserGroupDiscountConfig fxUserGroupDiscount = new FxUserGroupDiscountConfig();

        // 获取自己分销比例
        XmbUserGroup shareUserGroup = userGroupService.findXmbUserGroupById(shareUser.getFxGroupId());
        if (shareUserGroup != null) {
            fxUserGroupDiscount.setSelfBonusDiscount(shareUserGroup.getBonusDiscount());
            fxUserGroupDiscount.setSelfScoreDiscount(shareUserGroup.getScoreDiscount());
        }

        // 获取a分销比例
        if (shareUser.getaHigherId() != null && shareUser.getaHigherId() > 0) {
            XcxUser a = new XcxUser();
            a.setId(shareUser.getaHigherId());
            a = userService.selectOneUser(a);
            if (a != null) {
                XmbUserGroup aGroup = userGroupService.findXmbUserGroupById(a.getFxGroupId());
                if (aGroup != null) {
                    fxUserGroupDiscount.setABonusDiscount(aGroup.getBonusDiscount());
                    fxUserGroupDiscount.setAScoreDiscount(aGroup.getScoreDiscount());
                }
            }
        }


        // 获取b分销比例
        if (shareUser.getbHigherId() != null && shareUser.getbHigherId() > 0) {
            XcxUser b = new XcxUser();
            b.setId(shareUser.getbHigherId());
            b = userService.selectOneUser(b);
            if (b != null) {
                XmbUserGroup bGroup = userGroupService.findXmbUserGroupById(b.getFxGroupId());
                if (bGroup != null) {
                    fxUserGroupDiscount.setBBonusDiscount(bGroup.getBonusDiscount());
                    fxUserGroupDiscount.setBScoreDiscount(bGroup.getScoreDiscount());
                }
            }
        }


        // 获取c分销比例
        if (shareUser.getcHigherId() != null && shareUser.getcHigherId() > 0) {
            XcxUser c = new XcxUser();
            c.setId(shareUser.getcHigherId());
            c = userService.selectOneUser(c);
            if (c != null) {
                XmbUserGroup cGroup = userGroupService.findXmbUserGroupById(c.getFxGroupId());
                if (cGroup != null) {
                    fxUserGroupDiscount.setCBonusDiscount(cGroup.getBonusDiscount());
                    fxUserGroupDiscount.setCScoreDiscount(cGroup.getScoreDiscount());
                }
            }
        }


        // 获取w分销比例
        if (shareUser.getwHigherId() != null && shareUser.getwHigherId() > 0) {
            XcxUser w = new XcxUser();
            w.setId(shareUser.getwHigherId());
            w = userService.selectOneUser(w);
            if (w != null) {
                XmbUserGroup wGroup = userGroupService.findXmbUserGroupById(w.getFxGroupId());
                if (wGroup != null) {
                    fxUserGroupDiscount.setWBonusDiscount(wGroup.getBonusDiscount());
                    fxUserGroupDiscount.setWScoreDiscount(wGroup.getScoreDiscount());
                }
            }
        }
        return fxUserGroupDiscount;
    }



    @Transactional
    private Long insertDb(XcxUser xcxUser,XcxUser shareUser,XmbSpreadRewardSetting spreadRewardSetting,FxUserGroupDiscountConfig discountConfig) {

        boolean isNeedGift
                = sprendRewardRecordService.checkIsNeedGiftReward(xcxUser.getId(),spreadRewardSetting.getActivityId(),spreadRewardSetting.getPath());
        if (!isNeedGift) {
            logger.error("当前用户已经发送过奖励");
            return 0L;
        }
        // 写入各个配置的流水
        // 奖金
        if (RewardTypeEnum.bonus.name().equals(spreadRewardSetting.getPromotionRewardType())) {
            this.saveBonusBlotter(shareUser.getId(),
                    NumberUtils.getRoundDownBonusNumber(spreadRewardSetting.getPromotionSelfReward().multiply(discountConfig.getSelfBonusDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveBonusBlotter(shareUser.getaHigherId(),
                    NumberUtils.getRoundDownBonusNumber(spreadRewardSetting.getPromotionAReward().multiply(discountConfig.getABonusDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveBonusBlotter(shareUser.getbHigherId(),
                    NumberUtils.getRoundDownBonusNumber(spreadRewardSetting.getPromotionBReward().multiply(discountConfig.getBBonusDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveBonusBlotter(shareUser.getcHigherId(),
                    NumberUtils.getRoundDownBonusNumber(spreadRewardSetting.getPromotionCReward().multiply(discountConfig.getCBonusDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveBonusBlotter(shareUser.getwHigherId(),
                    NumberUtils.getRoundDownBonusNumber(spreadRewardSetting.getPromotionWReward().multiply(discountConfig.getWBonusDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());

        }

        // 积分
        if (RewardTypeEnum.score.name().equals(spreadRewardSetting.getPromotionRewardType())) {
            this.saveScoreBlotter(shareUser.getId(),
                    NumberUtils.getRoundDownScoreNumber(spreadRewardSetting.getPromotionSelfReward().multiply(discountConfig.getSelfScoreDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveScoreBlotter(shareUser.getaHigherId(),
                    NumberUtils.getRoundDownScoreNumber(spreadRewardSetting.getPromotionAReward().multiply(discountConfig.getAScoreDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveScoreBlotter(shareUser.getbHigherId(),
                    NumberUtils.getRoundDownScoreNumber(spreadRewardSetting.getPromotionBReward().multiply(discountConfig.getBScoreDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveScoreBlotter(shareUser.getcHigherId(),
                    NumberUtils.getRoundDownScoreNumber(spreadRewardSetting.getPromotionCReward().multiply(discountConfig.getCScoreDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
            this.saveScoreBlotter(shareUser.getwHigherId(),
                    NumberUtils.getRoundDownScoreNumber(spreadRewardSetting.getPromotionWReward().multiply(discountConfig.getWScoreDiscount())),
                    spreadRewardSetting,
                    shareUser.getSupplierId());
        }

        // 余额
//        if (RewardTypeEnum.balance.name().equals(spreadRewardSetting.getPromotionRewardType())) {
//            this.saveBalanceBlotter(shareUser.getId(),spreadRewardSetting.getPromotionSelfReward(), spreadRewardSetting,shareUser.getSupplierId());
//            this.saveBalanceBlotter(shareUser.getaHigherId(),spreadRewardSetting.getPromotionAReward(),spreadRewardSetting,shareUser.getSupplierId());
//            this.saveBalanceBlotter(shareUser.getbHigherId(),spreadRewardSetting.getPromotionBReward(),spreadRewardSetting,shareUser.getSupplierId());
//            this.saveBalanceBlotter(shareUser.getcHigherId(),spreadRewardSetting.getPromotionCReward(),spreadRewardSetting,shareUser.getSupplierId());
//            this.saveBalanceBlotter(shareUser.getwHigherId(),spreadRewardSetting.getPromotionWReward(),spreadRewardSetting,shareUser.getSupplierId());
//        }

        // 记录触发记录
        XmbSpreadRewardRecord rewardRecord = new XmbSpreadRewardRecord();
        rewardRecord.setUserId(xcxUser.getId());
        rewardRecord.setActivityId(spreadRewardSetting.getActivityId());
        rewardRecord.setPath(spreadRewardSetting.getPath());
        return sprendRewardRecordService.saveSprendRewardRecord(rewardRecord);
    }

    /**
     * 保存奖金流水
     * @param uid
     * @param exchangeAmount
     * @param spreadRewardSetting
     * @param supplierId
     */
    private void saveBonusBlotter(Long uid, BigDecimal exchangeAmount,XmbSpreadRewardSetting spreadRewardSetting,String supplierId) {
        if (exchangeAmount.compareTo(BigDecimal.ZERO) == 1
                && uid!= null
                && uid > 0) {
            XmbUserBonusBlotter bonusBlotter = new XmbUserBonusBlotter();
            bonusBlotter.setUserId(uid);
            bonusBlotter.setExchangeAmount(exchangeAmount);
            bonusBlotter.setTotalAmount(bonusService.getTotalBonus(uid).add(exchangeAmount));
            bonusBlotter.setTypeId(spreadRewardSetting.getActivityId());
            bonusBlotter.setExchangeRemark(spreadRewardSetting.getPath());
            bonusBlotter.setExchangeType(ExchangeTypeEnum.share_reward.name());
            bonusBlotter.setSupplierId(supplierId);
            bonusBlotter.setExchangeTitle("营销奖励");
            bonusService.saveBonusBlotter(bonusBlotter);
        }
    }

    /**
     * 保存积分流水
     * @param uid
     * @param exchangeAmount
     * @param spreadRewardSetting
     * @param supplierId
     */
    private void saveScoreBlotter(Long uid, BigDecimal exchangeAmount,XmbSpreadRewardSetting spreadRewardSetting,String supplierId) {
        if (exchangeAmount.compareTo(BigDecimal.ZERO) == 1
                && uid!= null
                && uid > 0) {
            XmbUserScoreBlotter scoreBlotter = new XmbUserScoreBlotter();
            scoreBlotter.setUserId(uid);
            scoreBlotter.setExchangeAmount(exchangeAmount);
            scoreBlotter.setTotalAmount(scoreService.getTotalScore(uid).add(exchangeAmount));
            scoreBlotter.setTypeId(spreadRewardSetting.getActivityId());
            scoreBlotter.setExchangeRemark(spreadRewardSetting.getPath());
            scoreBlotter.setExchangeType(ExchangeTypeEnum.share_reward.name());
            scoreBlotter.setSupplierId(supplierId);
            scoreBlotter.setExchangeTitle("营销奖励");
            scoreService.saveScoreBlotter(scoreBlotter);
        }
    }


//    private void saveBalanceBlotter(Long uid, BigDecimal exchangeAmount,XmbSpreadRewardSetting spreadRewardSetting,String supplierId) {
//        if (exchangeAmount.compareTo(BigDecimal.ZERO) == 1
//                && uid!= null
//                && uid > 0) {
//            XmbUserBalanceBlotter balanceBlotter = new XmbUserBalanceBlotter();
//            balanceBlotter.setUserId(uid);
//            balanceBlotter.setExchangeAmount(exchangeAmount);
//            balanceBlotter.setTotalAmount(balanceService.getTotalBalance(uid).add(exchangeAmount));
//            balanceBlotter.setTypeId(spreadRewardSetting.getActivityId());
//            balanceBlotter.setExchangeRemark(spreadRewardSetting.getPath());
//            balanceBlotter.setExchangeType(ExchangeTypeEnum.share_reward.name());
//            balanceBlotter.setSupplierId(supplierId);
//            balanceBlotter.setExchangeTitle("营销奖励");
//            balanceService.saveBalanceBlotter(balanceBlotter);
//        }
//    }



}
